//
// Created by Administrator on 2021/5/4.
//

/*
给你单链表的头节点 head ，请你反转链表，并返回反转后的链表。

示例 1：
输入：head = [1,2,3,4,5]
输出：[5,4,3,2,1]

示例 2：
输入：head = [1,2]
输出：[2,1]

示例 3：
输入：head = []
输出：[]

提示：
链表中节点的数目范围是 [0, 5000]
-5000 <= Node.val <= 5000

来源：力扣（LeetCode）
链接：https://leetcode-cn.com/problems/reverse-linked-list
著作权归领扣网络所有。商业转载请联系官方授权，非商业转载请注明出处。*/
#include <iostream>
#include <vector>

using namespace std;

// Definition for singly-linked list.
struct ListNode {
    int val;
    ListNode *next;

    ListNode() : val(0), next(nullptr) {}

    ListNode(int x) : val(x), next(nullptr) {}

    ListNode(int x, ListNode *next) : val(x), next(next) {}
};

void printList(ListNode *node) {
    auto firstNode = node;
    do {
        std::cout << firstNode->val << std::endl;
        firstNode = firstNode->next;
    } while (firstNode != nullptr);
}

class Solution {
public:
    ListNode *reverseList(ListNode *head) {
        // 用vector 储存所有节点
        if (head == nullptr) return head;
        vector<ListNode *> v;
        while (head) {
            v.push_back(head);
            head = head->next;
        }
        for (auto i = v.rbegin(); i != v.rend() - 1; ++i) {
            (*i)->next = *(i + 1);
        }
        v[0]->next = nullptr;
        return v.back();
    }
};

class Solution2 {
public:
    ListNode *reverseList(ListNode *head) {
        // 记录前一个节点
        ListNode *prev = nullptr;
        ListNode *curr = head;
        while (curr) {
            ListNode *next = curr->next;
            curr->next = prev;
            prev = curr;
            curr = next;
        }
        return prev;
    }
    ListNode* reverseList2(ListNode* head) { // 递归版本
        if (!head || !head->next) {
            return head;
        }
        ListNode* newHead = reverseList2(head->next);
        head->next->next = head;
        head->next = nullptr;
        return newHead;
    }


};

int main() {
    ListNode n1{1}, n2{2}, n3{3}, n4{4}, n5{5};
    n1.next = &n2;
    n2.next = &n3;
    n3.next = &n4;
    n4.next = &n5;
    Solution sol;
    printList(&n1);
    printList(sol.reverseList(&n1));
    return 0;
}